package com.gwt.server;

import java.io.IOException;
import java.util.List;
import java.util.Random;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import com.gwt.server.domain.Beer;
import com.gwt.server.domain.BeerStyle;
import com.gwt.server.generator.BeerGenerator;
import com.gwt.server.generator.store.BeerSource;

public class BeerListService implements Filter {

	private static final ThreadLocal<BeerSource> BEER_SOURCE = new ThreadLocal<BeerSource>();

	public static Beer createBeer() {
		checkBeerSource();
		Beer person = BeerGenerator.makeBeer();
		BEER_SOURCE.get().persist(person);
		return person;
	}

	public static Beer findBeer(String id) {
		checkBeerSource();
		return BEER_SOURCE.get().findBeer(id);
	}

	public static List<Beer> getBeerList(int startIndex, int maxCount) {
		checkBeerSource();
		return BEER_SOURCE.get().getBeerList(startIndex, maxCount);
	}

	public static Beer getRandomBeer() {
		BeerSource source = BEER_SOURCE.get();
		return source.getBeerList(new Random().nextInt(source.countBeers()), 1).get(0);
	}

	public static void persist(BeerStyle address) {
		checkBeerSource();
		BEER_SOURCE.get().persist(address);
	}

	public static void persist(Beer person) {
		checkBeerSource();
		BEER_SOURCE.get().persist(person);
	}

	private static void checkBeerSource() {
		if (BEER_SOURCE.get() == null) {
			throw new IllegalStateException("Calling service method outside of HTTP request");
		}
	}

	private BeerSource backingStore;

	public void destroy() {
	}

	public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
		try {
			BEER_SOURCE.set(BeerSource.of(backingStore));
			chain.doFilter(req, resp);
		} finally {
			BEER_SOURCE.set(null);
		}
	}

	public void init(FilterConfig config) {
		backingStore = (BeerSource) config.getServletContext().getAttribute(BeerListService.class.getName());
		if (backingStore == null) {
			backingStore = BeerSource.of(BeerGenerator.getMoreBeer(250));
			config.getServletContext().setAttribute(BeerListService.class.getName(), backingStore);
		}
	}
}
